/*
 * Copyright (C) 2004-2005, Universidade Federal de Campina Grande. All rights reserved.
 */
package org.jheuristics.neighborhood;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jheuristics.Individual;

/**
 * TODO
 *
 * @author Marcell Manfrin, marcell@ourgrid.org, Jan 9, 2006
 */
public class NeighborhoodUtils {

	/**
	 * TODO
	 * 
	 * @param individuals
	 * @param strategy
	 * @return
	 */
	public static Map createNeighborhoodMap(List individuals, Neighbor strategy) {
		verifyListOfIndidividuals(individuals);
		verifyNeighborStrategy(strategy);

		Map neighborhood = new HashMap();
		for (Iterator it1 = individuals.iterator(); it1.hasNext();) {
			Individual individual = (Individual) it1.next();
			neighborhood.put(individual, createNeighborhoodTrusted(individual, individuals, strategy));
		}
		return neighborhood;
	}

	/**
	 * TODO
	 * 
	 * @param individual
	 * @param possibleNeighbors
	 * @param strategy
	 * @return
	 */
	public static Set createNeighborhood(Individual individual, List possibleNeighbors, Neighbor strategy) {
		verifyIndividual(individual);
		verifyListOfIndidividuals(possibleNeighbors);
		verifyNeighborStrategy(strategy);
		return createNeighborhoodTrusted(individual, possibleNeighbors, strategy);
	}

	/**
	 * TODO
	 * 
	 * @param individual
	 * @param possibleNeighbors
	 * @param strategy
	 * @return
	 */
	private static Set createNeighborhoodTrusted(Individual individual, List possibleNeighbors, Neighbor strategy) {
		Set neighborhood = new HashSet();
		for (Iterator it = possibleNeighbors.iterator(); it.hasNext();) {
			Individual other = (Individual) it.next();
			if (!individual.equals(other)) {
				if (strategy.neighbor(individual, other)) {
					neighborhood.add(other);
				}
			}
		}
		return neighborhood;
	}

	/**
	 * TODO
	 * 
	 * @param individual
	 */
	private static void verifyIndividual(Individual individual) {
		if (null == individual) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
	}

	/**
	 * TODO
	 * 
	 * @param individuals
	 */
	private static void verifyListOfIndidividuals(List individuals) {
		if (null == individuals) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
		for (Iterator it = individuals.iterator(); it.hasNext();) {
			Object obj = it.next();
			if (null == obj) {
				// TODO: ERROR MSG
				throw new NullPointerException();
			}
			if (!(obj instanceof Individual)) {
				// TODO: ERROR MSG
				throw new ClassCastException();
			}
		}
	}

	/**
	 * TODO
	 * 
	 * @param strategy
	 */
	private static void verifyNeighborStrategy(Neighbor strategy) {
		if (null == strategy) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
	}

}
